//
//  QSRsaManager.swift
//  TestSwift
//
//  Created by Song on 2018/5/21.
//  Copyright © 2018年 Song. All rights reserved.
//
//  SwiftyRSA这个第三方还有其他一些加密方法

import UIKit
import SwiftyRSA

/// 公私钥生成方式
enum QSKeyGenerateMode {
    case der                // der文件
    case pem                // pem文件
    case pemString          // pem字符串
    case base64String       // base64字符串
    case data               // 二进制数据
    case secKey             // 密钥
}

class QSRsaManager: NSObject {
    /// 创建公钥
    ///
    /// - Parameters:
    ///   - pubilc: 要生成公钥的文件或字符串
    ///   - model: 公钥生成方式
    /// - Returns: 公钥
    class func qs_generatePublicKey(pubilc: Any, model: QSKeyGenerateMode) -> PublicKey? {
        var publickey: PublicKey?
        
        switch model {
        case .der:
            publickey = try? PublicKey(derNamed: pubilc as! String)
        case .pem:
            publickey = try? PublicKey(pemNamed: pubilc as! String)
        case .pemString:
            publickey = try? PublicKey(pemEncoded: pubilc as! String)
        case .base64String:
            publickey = try? PublicKey(base64Encoded: pubilc as! String)
        case .data:
            publickey = try? PublicKey(data: pubilc as! Data)
        case .secKey:
            publickey = try? PublicKey(reference: pubilc as! SecKey)
        }
        
        return publickey
    }
    
    /// 创建私钥
    ///
    /// - Parameters:
    ///   - privateKey: 要生成私钥的文件或字符串
    ///   - model: 私钥生成方式
    /// - Returns: 私钥
    class func qs_generatePrivateKey(privateKey: Any, model: QSKeyGenerateMode) -> PrivateKey? {
        var privatekey: PrivateKey?
        
        switch model {
        case .der:
            privatekey = try? PrivateKey(derNamed: privateKey as! String)
        case .pem:
            privatekey = try? PrivateKey(pemNamed: privateKey as! String)
        case .pemString:
            privatekey = try? PrivateKey(pemEncoded: privateKey as! String)
        case .base64String:
            privatekey = try? PrivateKey(base64Encoded: privateKey as! String)
        case .data:
            privatekey = try? PrivateKey(data: privateKey as! Data)
        case .secKey:
            privatekey = try? PrivateKey(reference: privateKey as! SecKey)
        }
        
        return privatekey
    }
    
    /// 公钥加密
    ///
    /// - Parameters:
    ///   - text: 要加密的内容
    ///   - publicKey: 公钥
    /// - Returns: 加密后的字符串，加密失败返回nil
    class func qs_rsaEncode(_ text: String, publicKey: PublicKey) -> String? {
        do {
            let clear = try ClearMessage(string: text, using: .utf8)
            let encryptedStr = try clear.encrypted(with: publicKey, padding: .PKCS1)
            
            return encryptedStr.base64String
        } catch {
            #if DEBUG
            debugPrint(error)
            #endif
            return nil
        }
    }
    
    /// 私钥解密
    ///
    /// - Parameters:
    ///   - ciphertext: 要解密的内容
    ///   - privateKey: 私钥
    /// - Returns: 解密后的字符串，解密失败返回nil
    class func qs_rsaDecode(_ ciphertext: String, privateKey: PrivateKey) -> String? {
        do {
            let encrypted = try EncryptedMessage(base64Encoded: ciphertext)
            let decryptedStr = try encrypted.decrypted(with: privateKey, padding: .PKCS1)
            
            let string = try decryptedStr.string(encoding: .utf8)
            return string
        } catch {
            #if DEBUG
            debugPrint(error)
            #endif
            return nil
        }
    }
    
    /// 私钥签名
    ///
    /// - Parameters:
    ///   - text: 要签名的内容
    ///   - privateKey: 私钥
    /// - Returns: 签名后的内容
    class func qs_sign(_ text: String, privateKey: PrivateKey) -> String? {
        do {
            let clear = try ClearMessage(string: text, using: .utf8)
            let signature = try clear.signed(with: privateKey, digestType: .sha1)
            
            let base64String = signature.base64String
            return base64String
        } catch {
            #if DEBUG
            debugPrint(error)
            #endif
            return nil
        }
    }
    
    /// 公钥验签
    ///
    /// - Parameters:
    ///   - text: 要签名的内容
    ///   - sign: 要验签的内容
    ///   - publicKey: 公钥
    /// - Returns: 验签是否成功
    class func qs_verifySign(text: String, sign: String, publicKey: PublicKey) -> Bool? {
        do {
            let signature = try Signature(base64Encoded: sign)
            
            let clear = try ClearMessage(string: text, using: .utf8)
            let isSuccessful = try clear.verify(with: publicKey, signature: signature, digestType: .sha1)
            
            return isSuccessful
        } catch {
            #if DEBUG
            debugPrint(error)
            #endif
            return nil
        }
    }
    
    /// 生成公私钥对
    /// 只有10系统以后的才有这个方法
    ///
    /// - Returns: (私钥， 公钥)
    @available(iOS 10.0, *)
    class func qs_generateRSAKeyPair() -> (PrivateKey, PublicKey)? {
        let keyPair = try? SwiftyRSA.generateRSAKeyPair(sizeInBits: 2048)
        
        if let keyP = keyPair {
            let privateKey = keyP.privateKey
            let publicKey = keyP.publicKey
            
            return (privateKey, publicKey)
        }
        
        return nil
    }
}
